﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Net.Event;
using Net.Helper;
using Net.Table.Solvers;

namespace Net.Table
{
    public class TypeSolver
    {
        public static Dictionary<string, ITypeSolver> SolverTypes = new();

        public static bool TryGetValue(string columnType, out ITypeSolver typeSolver)
        {
            if (SolverTypes.TryGetValue(columnType, out typeSolver))
                return true;
            var type = AssemblyHelper.GetTypeNotOptimized(columnType);
            if (type != null && type.IsEnum)
            {
                typeSolver = Activator.CreateInstance(typeof(EnumTypeSolver<>).MakeGenericType(type)) as ITypeSolver;
                SolverTypes.Add(columnType, typeSolver);
                return true;
            }
            NDebug.LogError($"表类型:{columnType}没有类型求解器, 请实现!");
            return false;
        }

        static TypeSolver()
        {
            InitTypeSolverCollectors();
        }

        public static void InitTypeSolverCollectors()
        {
            if (SolverTypes.Count > 0)
                return;
            var assemblies = AppDomain.CurrentDomain.GetAssemblies();
            var @interface = typeof(ITypeSolverCollector);
            foreach (var assemblie in assemblies)
            {
                var assemblyName = assemblie.GetName();
                if (assemblyName.Name.StartsWith("mscorlib") || assemblyName.Name.StartsWith("System"))
                    continue;
                if (assemblyName.Name.StartsWith("dnlib") || assemblyName.Name.StartsWith("MySql"))
                    continue;
                if (assemblyName.Name.StartsWith("UniTask") || assemblyName.Name.StartsWith("Microsoft"))
                    continue;
                if (assemblyName.Name.StartsWith("netstandard"))
                    continue;
#if !(UNITY_STANDALONE || UNITY_ANDROID || UNITY_IOS || UNITY_WSA || UNITY_WEBGL)
                if (assemblyName.Name.StartsWith("UnityEngine"))
                    continue;
#endif
                if (assemblie.IsDynamic)
                    continue;
                Type[] types = null;
                try
                {
                    types = assemblie.GetTypes(); //这里会有时发生异常, 比如gdnet引用的unitask.dll是新版本, 而server引用了旧版本就会出错!
                }
                catch (ReflectionTypeLoadException ex)
                {
                    NDebug.LogError(ex);
                    foreach (var exception in ex.LoaderExceptions)
                    {
                        NDebug.LogError(exception);
                    }
                    throw;
                }
                foreach (var type in types)
                {
                    if (!type.IsClass || type.IsInterface || type.IsAbstract)
                        continue;
                    if (type.IsInterfaceType(@interface))
                    {
                        var collector = (ITypeSolverCollector)Activator.CreateInstance(type);
                        collector.Initialize();
                    }
                }
            }
        }
    }
}
